<script setup>
import { ref, onMounted } from 'vue'
import { useRouter } from 'vue-router'
import { ElMessage, ElMessageBox } from 'element-plus'
import { VideoCamera, Delete, ArrowRight, StarFilled } from '@element-plus/icons-vue'
import { pageSaves, deleteSaveById } from '@/api/save'
import { getMovie } from '@/api/movies'
import { profile } from '@/api/user'
import dayjs from 'dayjs'

const router = useRouter()

const items = ref([])
const total = ref(0)
const pageNo = ref(1)
const pageSize = ref(12)
const loading = ref(false)
const user = ref(null)
const movieMap = ref({})

const cleanUrl = (url) => (url ? String(url).replace(/`/g, '').trim() : '')
const posterSrc = (movie) => cleanUrl(movie?.posterUrl) || cleanUrl(movie?.imageUrl) || cleanUrl(movie?.poster) || cleanUrl(movie?.cover) || ''
const scoreText = (s) => {
  if (s === null || s === undefined || s === '') return '暂无评分'
  return typeof s === 'number' ? (s.toFixed ? s.toFixed(1) : s) : s
}
const fmtTime = (t) => {
  try { return dayjs(t).format('YYYY-MM-DD HH:mm') } catch { return t }
}

const enrichMovies = async (records) => {
  const mids = [...new Set(records.map(r => r.mid).filter(Boolean))]
  await Promise.all(mids.map(async mid => {
    if (movieMap.value[mid]) return
    try {
      const res = await getMovie(mid)
      if (res?.code === '200') {
        movieMap.value[mid] = res.data || {}
      }
    } catch (e) {
      // 忽略单条错误，避免中断整个列表
    }
  }))
}

const loadUser = async () => {
  try {
    const res = await profile()
    if (res?.code === '200') {
      user.value = res.data || null
    }
  } catch (e) {
    // 忽略用户信息错误，不影响收藏展示
  }
}

const loadPage = async () => {
  loading.value = true
  try {
    const res = await pageSaves({ pageNo: pageNo.value, pageSize: pageSize.value })
    if (res.code === '200') {
      items.value = res.data?.records || []
      total.value = res.data?.total || 0
      await enrichMovies(items.value)
    } else {
      ElMessage.error(res.msg || '加载收藏失败')
    }
  } catch (e) {
    // 错误由拦截器统一处理
  } finally {
    loading.value = false
  }
}

onMounted(async () => {
  const token = localStorage.getItem('token')
  if (!token) {
    ElMessage.info('请先登录后查看收藏')
    router.push('/login')
    return
  }
  await loadUser()
  await loadPage()
})

const handleSizeChange = (size) => { pageSize.value = size; pageNo.value = 1; loadPage() }
const handlePageChange = (page) => { pageNo.value = page; loadPage() }

const goHome = () => router.push('/')
const goDetail = (mid) => router.push(`/movie/${mid}`)

const removeSave = async (item) => {
  try {
    await ElMessageBox.confirm(`确定取消收藏《${item.mname || item.mid}》吗？`, '提示', { type: 'warning' })
    const res = await deleteSaveById(item.id)
    if (res.code === '200') {
      ElMessage.success(res.msg || '已取消收藏')
      // 本地更新，不必每次都重新拉取
      items.value = items.value.filter(s => s.id !== item.id)
      total.value = Math.max(0, (total.value || 0) - 1)
      if (!items.value.length && total.value > 0) {
        // 当前页为空时尝试刷新
        pageNo.value = Math.max(1, pageNo.value - 1)
        loadPage()
      }
    } else {
      ElMessage.error(res.msg || '取消失败')
    }
  } catch (e) {
    // 用户取消或请求错误
  }
}
</script>

<template>
  <div class="page saves" v-loading="loading">
    <!-- 顶部导航 -->
    <div class="topbar">
      <div class="brand" @click="goHome">
        <el-icon><VideoCamera /></el-icon>
        <span>我的收藏</span>
      </div>
      <div class="actions">
        <el-link type="primary" @click="goHome">首页</el-link>
      </div>
    </div>

    <!-- 英雄区 -->
    <section class="hero glass">
      <h1 class="title">我的收藏</h1>
      <p class="subtitle">你好，{{ (user?.nickname || user?.username || user?.uname || '影迷') }} · 共 {{ total }} 条收藏</p>
    </section>

    <!-- 列表区 -->
    <section class="content">
      <div v-if="items.length" class="grid">
        <el-card
          v-for="s in items"
          :key="s.id"
          class="card clickable"
          shadow="hover"
          @click="s.mid && goDetail(s.mid)"
        >
          <div class="card-header">
            <h3 class="name">{{ s.mname || '未命名电影' }}</h3>
            <el-tag type="success">已收藏</el-tag>
          </div>
          <div class="card-body">
             <div class="poster-sm" v-if="posterSrc(movieMap[s.mid])">
               <img :src="posterSrc(movieMap[s.mid])" :alt="s.mname || 'poster'">
             </div>
             <div class="info">
               <div class="name">{{ s.mname || movieMap[s.mid]?.mname || '未命名电影' }}</div>
               <div class="meta-row">
                 <span class="type">{{ movieMap[s.mid]?.type || '电影' }}</span>
                 <span class="rating" v-if="(movieMap[s.mid]?.rating || movieMap[s.mid]?.score)">
                   <el-icon class="star"><StarFilled /></el-icon>
                   {{ scoreText(movieMap[s.mid]?.rating || movieMap[s.mid]?.score) }}
                 </span>
               </div>
               <div class="save-time">收藏于：{{ fmtTime(s.stime || s.createdAt) }}</div>
             </div>
           </div>
          <div class="card-footer">
            <el-button type="primary" text @click.stop="goDetail(s.mid)">
              查看详情
              <el-icon style="margin-left:4px"><ArrowRight /></el-icon>
            </el-button>
            <el-button type="danger" text @click.stop="removeSave(s)">
              取消收藏
              <el-icon style="margin-left:4px"><Delete /></el-icon>
            </el-button>
          </div>
        </el-card>
      </div>
      <el-empty v-else description="暂无收藏" />

      <div class="pager" v-if="total > 0">
        <el-pagination
          background
          layout="total, sizes, prev, pager, next"
          :total="total"
          :page-sizes="[8,12,16,24]"
          :page-size="pageSize"
          :current-page="pageNo"
          @size-change="handleSizeChange"
          @current-change="handlePageChange"
        />
      </div>
    </section>
  </div>
</template>

<style scoped>
.page { min-height: 100vh; background: radial-gradient(1000px 500px at 10% 10%, rgba(99,102,241,0.15), transparent), radial-gradient(800px 400px at 90% 0%, rgba(16,185,129,0.12), transparent), #0b1020; color: #e5e7eb; }
.topbar { display: flex; align-items: center; justify-content: space-between; padding: 16px 24px; }
.brand { display: flex; align-items: center; gap: 8px; cursor: pointer; font-weight: 600; letter-spacing: 0.6px; }
.actions :deep(.el-link) { margin-left: 12px; }

.hero { margin: 16px auto 24px; padding: 28px 24px; max-width: 980px; border-radius: 16px; background: rgba(255,255,255,0.12); backdrop-filter: blur(12px); border: 1px solid rgba(255,255,255,0.22); }
.title { font-size: 24px; font-weight: 700; margin: 0 0 6px; }
.subtitle { margin: 0; color: #cfd3dc; }

.content { max-width: 980px; margin: 0 auto 40px; padding: 0 12px; }
.grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; }
@media (max-width: 1000px) { .grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 680px) { .grid { grid-template-columns: 1fr; } }

.card { background: rgba(255,255,255,0.12); border-radius: 14px; border: 1px solid rgba(255,255,255,0.22); box-shadow: 0 6px 18px rgba(0,0,0,0.35); }
.card :deep(.el-card__body) { padding: 12px; }
.card-header { display: flex; align-items: center; justify-content: space-between; }
.name { font-weight: 600; color: #f1f5f9; }
.card-body { color: #e5e7eb; }
.row { display: flex; gap: 8px; align-items: center; margin: 6px 0; }
.card-footer { display: flex; justify-content: flex-end; gap: 8px; padding-top: 6px; }

.poster-sm img { width: 100%; height: 180px; object-fit: cover; border-radius: 8px; display: block; }
.meta-row { display: flex; gap: 10px; align-items: center; margin-top: 6px; color: #dbeafe; }
.meta-row .type { padding: 2px 8px; border-radius: 999px; background: rgba(255,255,255,0.16); color: #f3f4f6; }
.meta-row .rating { display: inline-flex; align-items: center; gap: 4px; color: #fde68a; }
.star { color: #fbbf24; }
.save-time { margin-top: 6px; color: #cbd5e1; }

.pager { display: flex; justify-content: center; margin-top: 16px; }
.clickable { cursor: pointer; }
</style>